// <copyright file="IniReader.cs" company="SharpSTS">
// Copyright (c) 2007, 2008 All Right Reserved, http://sharpsts.com/
//
// This source is subject to the Microsoft Permissive License.
// Please see the License.txt file for more information.
// All other rights reserved.
//
// THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY 
// KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// </copyright>
// <author>Microsoft/ Barry Dorrans</author>
// <date>2008-06-20</date>
// <summary>A class for reading INI files.</summary>

namespace SharpSTS.CardWriter
{
    using System;
    using System.Runtime.InteropServices;

    /// <summary>
    /// Represents an ini file.
    /// </summary>
    internal class IniFile
    {
        /// <summary>
        /// A collection of sections within the ini file.
        /// </summary>
        private readonly Section[] sections;

        /// <summary>
        /// Initializes a new instance of the <see cref="IniFile"/> class.
        /// </summary>
        /// <param name="fileName">Name of the ini file.</param>
        public IniFile(string fileName)
        {
            if (!System.IO.File.Exists(fileName))
            {
                throw new System.IO.FileNotFoundException("File " + fileName + " Not found");
            }

            byte[] buffer = new byte[32767];
            string[] temporaryKey;

            int i = GetPrivateProfileString(null, null, null, buffer, 32767, fileName);
            if (i == 0)
            {
                this.sections = new Section[0];
                return;
            }

            string[] sectionName = System.Text.Encoding.GetEncoding(1252).GetString(buffer, 0, i).TrimEnd((char)0).Split((char)0);
            this.sections = new Section[sectionName.Length];
            for (int j = 0; j < sectionName.Length; j++)
            {
                i = GetPrivateProfileString(sectionName[j], null, null, buffer, 32767, fileName);
                temporaryKey = System.Text.Encoding.GetEncoding(1252).GetString(buffer, 0, i).TrimEnd((char)0).Split((char)0);
                Key[] keys = new Key[temporaryKey.Length];
                for (int k = 0; k < temporaryKey.Length; k++)
                {
                    i = GetPrivateProfileString(sectionName[j], temporaryKey[k], null, buffer, 32767, fileName);
                    keys[k] = new Key(temporaryKey[k], System.Text.Encoding.GetEncoding(1252).GetString(buffer, 0, i).TrimEnd((char)0));
                }

                this.sections[j] = new Section(sectionName[j], keys);
            }
        }

        /// <summary>
        /// Gets the <see cref="SharpSTS.CardWriter.Section"/> at the specified index.
        /// </summary>
        /// <param name="index">The index of the Section to get.</param>
        /// <value>The <see cref="SharpSTS.CardWriter.Section"/> at the specified index.</value>
        public Section this[string index]
        {
            get
            {
                foreach (Section s in this.sections)
                {
                    if (s.Name.Equals(index, StringComparison.CurrentCultureIgnoreCase))
                    {
                        return s;
                    }
                }

                return new Section("", new Key[0]);
            }
        }

        /// <summary>
        /// Retrieves a string from the specified section in an initialization file.
        /// </summary>
        /// <param name="section">
        /// The name of the section containing the key name. If this parameter is NULL, the GetPrivateProfileString function copies all section 
        /// names in the file to the supplied buffer.
        /// </param>
        /// <param name="key">
        /// The name of the key whose associated string is to be retrieved. If this parameter is NULL, all key names 
        /// in the section specified by the lpAppName parameter are copied to the buffer specified by the lpReturnedString parameter.</param>
        /// <param name="defaultString">
        /// A default string. If the lpKeyName key cannot be found in the initialization file, GetPrivateProfileString copies the 
        /// default string to the lpReturnedString buffer. If this parameter is NULL, the default is an empty string, "".
        /// </param>
        /// <param name="returnBuffer">A pointer to the buffer that receives the retrieved string.</param>
        /// <param name="bufferLength">The size of the buffer pointed to by the lpReturnedString parameter, in characters.</param>
        /// <param name="fileName">
        /// The name of the initialization file. If this parameter does not contain a full path to the file, the system searches for the file 
        /// in the Windows directory.
        /// </param>
        /// <returns>A string from the specified section in an initialization file.</returns>
        [DllImport("kernel32", SetLastError = true)]
        private static extern int GetPrivateProfileString(string section, string key, string defaultString, byte[] returnBuffer, int bufferLength, string fileName);
    }
}
